package com.shuangzh.brief.rpc;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.ServerSocket;
import java.net.Socket;

import org.springframework.context.SmartLifecycle;

/**
 * RPC 服务端， 启动ServerSocket对外提供服务。
 * @author shuangzh
 *
 */
public class ServerProxy implements SmartLifecycle {
	
	/**
	 * 服务代理类
	 */
	private ServiceProxy serviceproxy = null;
	
	/**
	 * 提供服务的端口
	 */
	private int port = 9090;

	public ServiceProxy getServiceproxy() {
		return serviceproxy;
	}
	
	/**
	 * 设置服务代理类
	 * @param serviceproxy
	 */
	public void setServiceproxy(ServiceProxy serviceproxy) {
		this.serviceproxy = serviceproxy;
	}

	public int getPort() {
		return port;
	}
	
	/**
	 * 设置服务端口
	 * @param port
	 */
	public void setPort(int port) {
		this.port = port;
	}

	private ServerSocket ssocket = null;
	
	/**
	 * 处理客户端的调用请求
	 * @author shuangzh
	 *
	 */
	class Processor implements Runnable {

		Socket socket = null;
		ObjectOutputStream out;
		ObjectInputStream in;

		Processor(Socket s) {
			this.socket = s;
			try {
				out = new ObjectOutputStream(socket.getOutputStream());
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			try {
				in = new ObjectInputStream(socket.getInputStream());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
		
		public void run() {
			while (true) {
				
				/**
				 * 接受服务端的请求数据，并调用 服务代理的方法，然后将结果返回给客户端
				 */
				try {
					RequestObject req = (RequestObject) in.readObject();
					if (req.getArgs() == null) {
						req.setArgs(new Object[] {});
					}
					
//					Object result = serviceproxy.call(req.getMethodName(),
//							req.getArgs());
					
					Object result = serviceproxy.call(req.getMethodName(), req.getParameterTypes(), req.getArgs());
					
					ResponseObject rsp = new ResponseObject();
					rsp.setId(req.getId());
					rsp.setResult(result);
					out.writeObject(rsp);
				} catch (ClassNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					break;
				} catch (NoSuchMethodException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalArgumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		}

	}

	public boolean isRunning() {
		// TODO Auto-generated method stub
		return false;
	}
	
	/**
	 * 启动服务服务。 
	 * 启动ServerSocket, 启动socket监听线程。
	 */
	public void start() {
		assert (serviceproxy != null);

		try {
			ssocket = new ServerSocket(port);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		Thread thread = new Thread(new Runnable() {

			public void run() {

				while (true) {

					try {
						Socket s = ssocket.accept();

						Processor p = new Processor(s);
						Thread t = new Thread(p);
						t.setDaemon(true);
						t.start();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		});

		thread.setDaemon(false);
		thread.start();

	}

	public void stop() {
		// TODO Auto-generated method stub

	}

	public int getPhase() {
		// TODO Auto-generated method stub
		return 0;
	}

	public boolean isAutoStartup() {
		// TODO Auto-generated method stub
		return false;
	}

	public void stop(Runnable arg0) {
		// TODO Auto-generated method stub

	}

	public static void main(String[] args) {
		ServerProxy server = new ServerProxy();
		ServiceProxy service = new ServiceProxy();

		SimpleImpl actor = new SimpleImpl();
		
		//设置被代理的对象
		service.setActor(actor);
		// 设置代理的接口
		service.setClazz(SimpleFace.class);
		
		//设置serviceproxy
		server.setServiceproxy(service);
		
		//初始化，并启动RPC服务端
		server.start();
	}
}
